﻿/*
 * jQuery object to handle interactions on the character pages.
 */
(function ($) {
    var settings = {
        raceChangeActionUrl: '',
        classChangeActionUrl: '',
        headerContainerSelector: '.header-container',
        tableChangeCallback: null,
        guildChangeActionUrl: '',
        guildChangeCallback: null,
        recordContainerSelector: '',
        addRecordItemUrl: '',
        addRecordCallback: null,
        headerUrl: '',
        updateRecordItemUrl: '',
        updateRecordCallback: null,
        recordsUrl: '',
        headerRefreshedCallback: null,
        updateNameUrl: '',
        saveUrl: '',
        silhouetteUrl: '',
        silhouetteContainerSelector: '.silhouette-container',
        silhouetteRefreshedCallback: null,
        recordsRefreshedCallback: null
    };

    var busy = false;

    var methods = {
        init: function (options) {
            $('.message-box').hide();

            settings = $.extend(settings, options);

            bindHeaderEvents();

            bindAdventureRecordEvents();

            bindUpdateRecordEvents();
        },
        refreshRecords: function () {
            _refreshRecords();
        },
        refreshHeader: function (content) {
            _refreshHeader();
        },
        refreshSilhouette: function (content) {
            _refreshSilhouette();
        },
        updateName: function (name) {
            var url = settings.updateNameUrl;

            url += '?name=' + encodeURI(name);

            doAjaxJsonGet(url,
                function (data) {
                    if (data.Data) {
                        location.href = data.Data;
                    }
                },
                function (data) {
                    showWarning(data);
                });
        }
    };

    $.fn.character = function (method) {

        // Method calling logic
        if (methods[method]) {
            return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
        } else if (typeof method === 'object' || !method) {
            return methods.init.apply(this, arguments);
        } else {
            $.error('Method ' + method + ' does not exist on character object.');
        }

    };

    /*
    * Bind jquery events handlers for elements of the header.
    */
    function bindHeaderEvents() {
        // Set up the race and class ddl drop down change handlers.
        if (settings.raceChangeActionUrl) {
            $('.raceList').change(function () {
                var changeUrl = settings.raceChangeActionUrl;

                if ($(this).val() != '') {
                    var race = $(this).val()
                    changeUrl += "?race=" + race;

                    doAjaxGet(changeUrl, settings.headerContainerSelector,
                        function () {
                            if (settings.tableChangeCallback)
                                settings.tableChangeCallback();

                            showMessage('Changed character race to ' + race);

                            bindHeaderEvents(); // ensure these events are re bound to new html elements.
                        },
                        function (data) { // error handler
                            showMessage('Failed to change character race to ' + race);
                        }
                    );
                };
            });
        }

        if (settings.classChangeActionUrl) {
            $('.classList').change(function () {
                var changeUrl = settings.classChangeActionUrl;

                if ($(this).val() != '') {
                    var classX = $(this).val();
                    changeUrl += "?class=" + classX;

                    doAjaxGet(
                        changeUrl,
                        settings.headerContainerSelector,
                        function () {
                            if (settings.tableChangeCallback)
                                settings.tableChangeCallback();

                            showMessage('Changed character class to ' + classX);
                            bindHeaderEvents(); // ensure these events are re bound to new html elements.
                        },
                        function (data) { // error handler.
                            showMessage('Failed to change character class to ' + classX);
                        }
                    );
                };
            });
        }

        if (settings.guildChangeActionUrl) {
            $('.primaryGuildList, .secondaryGuildList, .tertiaryGuildList').change(function () {
                var changeUrl = settings.guildChangeActionUrl;

                var type = "primary";

                if ($(this).hasClass('secondaryGuildList'))
                    type = "secondary";
                else if ($(this).hasClass('tertiaryGuildList'))
                    type = "tertiary";

                var guildId = $(this).val();
                var guildName = $(this).text();

                if (!guildId)
                    guildId = '0';

                changeUrl += "?guildId=" + guildId + "&type=" + type;

                doAjaxGet(changeUrl, settings.headerContainerSelector,
                    function () {
                        if (settings.guildChangeCallback)
                            settings.guildChangeCallback();

                        showMessage('Changed ' + type + ' guild to ' + guildName);
                        bindHeaderEvents(); // ensure these events are re bound to new html elements.
                    },
                    function (data) {
                        showMessage('Failed to changed ' + type + ' guild to ' + guildName);
                        showWarning(data);
                    }

                );
            });
        }

        /* The save character button click. */
        if (settings.saveUrl) {
            $('.save-character a').click(function (event) {
                event.preventDefault();

                doAjaxGet(settings.saveUrl, null,
                    function () {
                        showMessage('Character saved ok.');
                    },
                    function (data) {
                        showErrorText('Failed to save.');
                        showWarning(data);
                    }
                );
            });
        }
    }

    /*
    * Bind all jquery events for the adventure record sidebar.
    */
    function bindAdventureRecordEvents() {
        $('#eventDate').datepicker({ dateFormat: 'dd/mm/yy', defaultDate: settings.dateToday });

        // Handle the add adventure record item form submit.
        $('#addRecordForm').submit(function (event) {
            event.preventDefault();

            if (busy)
                return;

            busy = true;

            var $this = $(this);

            var date = $('#eventDate').val();
            var name = $('#eventDescription').val();
            var points = $('#eventPoints').val();

            // validate date and number values.
            var formValid = true;

            if (!isValidDate(date)) {
                $('.date-error').html('Invalid date').show();
                setTimeout(function () {
                    $('.date-error').fadeOut(1000);
                }, 2000);
                formValid = false;
            }

            if (!isValidNumber(points)) {
                $('.points-error').html('Invalid number of points').show();
                setTimeout(function () {
                    $('.points-error').fadeOut(1000);
                }, 2000);
                formValid = false;
            }

            if (!formValid) {
                busy = false;
                return;
            }

            var url = settings.addRecordItemUrl;

            url += '?date=' + date + '&name=' + name + '&points=' + points;

            doAjaxGet(url, settings.recordContainerSelector,
                function () {
                    if (settings.addRecordCallback)
                        settings.addRecordCallback();

                    showMessage('Added adventure record: ' + name + ' with ' + points + ' points.');

                    bindAdventureRecordEvents(); // ensure these events are re-bound to new html elements.

                    _refreshHeader();
                    busy = false;
                },
                function (data) {
                    showErrorText('Failed to add adventure record: ' + name + ' with ' + points + ' points.');
                    showWarning(data);
                    busy = false;
                });
        });

        $('.date-error, .points-error').hide();

        // handle the remove record link click.
        $('.remove-record').click(function (event) {
            event.preventDefault();

            // get link url.
            var url = $(this).attr('href');

            if (busy)
                return;

            busy = true;

            doAjaxGet(url, null,
                function () {
                    if (settings.updateRecordCallback)
                        settings.updateRecordCallback();

                    showMessage('Adventure record removed.');

                    _refreshRecords();
                    _refreshHeader();
                    busy = false;
                },
                function (data) {
                    showErrorText('Failed to remove adventure record.');
                    showWarning(data);
                    busy = false;
                });
        });
    }

    function bindUpdateRecordEvents() {
        $('#eventDate').datepicker({ dateFormat: 'dd/mm/yy', defaultDate: settings.dateToday });

        // Handle the add adventure record item form submit.
        $('#updateRecordForm').submit(function (event) {
            event.preventDefault();

            if (busy)
                return;

            busy = true;

            var $this = $(this);

            var date = $('#eventDate').val();
            var name = $('#eventDescription').val();
            var points = $('#eventPoints').val();

            // validate date and number values.
            var formValid = true;

            if (!isValidDate(date)) {
                $('.date-error').html('Invalid date').show();
                setTimeout(function () {
                    $('.date-error').fadeOut(1000);
                }, 2000);
                formValid = false;
            }

            if (!isValidNumber(points)) {
                $('.points-error').html('Invalid number of points').show();
                setTimeout(function () {
                    $('.points-error').fadeOut(1000);
                }, 2000);
                formValid = false;
            }

            if (!formValid) {
                busy = false;
                return;
            }

            var url = settings.updateRecordItemUrl;

            url += '?date=' + date + '&name=' + name + '&points=' + points;

            doAjaxGet(url, null,
                function () {
                    if (settings.updateRecordCallback)
                        settings.updateRecordCallback();

                    showMessage('Updated adventure record: ' + name + ' with ' + points + ' points.');

                    busy = false;
                },
                function (data) {
                    showErrorText('failed to update adventure record: ' + name + ' with ' + points + ' points.');
                    showWarning(data);
                    busy = false;
                });
        });
    }

    function _refreshRecords() {
        doAjaxGet(
                settings.recordsUrl,
                settings.recordContainerSelector,
                function () {
                    // refresh jquery event binding.
                    bindAdventureRecordEvents();

                    if (settings.recordsRefreshedCallback)
                        settings.recordsRefreshedCallback();
                },
                showWarning);
    }


    function _refreshHeader() {
        // reload the header container content via ajax.
        doAjaxGet(
                settings.headerUrl,
                settings.headerContainerSelector,
                function () {
                    // refresh jquery event binding.
                    bindHeaderEvents();

                    if (settings.headerRefreshedCallback)
                        settings.headerRefreshedCallback();
                },
                showWarning);
    }

    function _refreshSilhouette() {
        // reload the header container content via ajax.
        doAjaxGet(
                settings.silhouetteUrl,
                settings.silhouetteContainerSelector,
                function () {
                    // refresh jquery event binding.
                    //bindHeaderEvents();

                    if (settings.silhouetteRefreshedCallback)
                        settings.silhouetteRefreshedCallback();
                },
                showWarning);
    }

})(jQuery);